package com.quartet.modules.multimedia.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quartet.api.ApiResult;
import com.quartet.api.MapServerException;
import com.quartet.api.ResultErrorEnum;
import com.quartet.modules.customer.service.TCustomerInfoService;
import com.quartet.modules.file.entity.ToolLocalStorage;
import com.quartet.modules.file.service.ToolLocalStorageService;
import com.quartet.modules.multimedia.dao.TMultimediaDao;
import com.quartet.modules.multimedia.dto.*;
import com.quartet.modules.multimedia.entity.TMultimedia;
import com.quartet.modules.order.entity.TOrder;
import com.quartet.modules.order.service.TOrderService;
import com.quartet.modules.service.aspect.AuthKeyValidated;
import com.quartet.modules.service.entity.TServiceInfo;
import com.quartet.modules.service.service.TServiceInfoService;
import com.quartet.modules.stock.entity.TTerminalStock;
import com.quartet.modules.stock.service.TTerminalStockService;
import com.quartet.modules.terminal.entity.TTerminalInfo;
import com.quartet.modules.terminal.service.TTerminalInfoService;
import com.quartet.utils.DateUtil;
import com.quartet.utils.StringUtils;
import com.quartet.utils.constant.MapServerConstant;
import com.quartet.utils.enums.MultimediaTypeEnum;
import com.quartet.utils.enums.OrderStatusEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 多媒体(TOrder)表控制层
 *
 * @author makejava
 * @since 2021-05-04 16:40:24
 */
@RestController
@RequestMapping("file")
@Slf4j
@Api(tags = "业务：多媒体管理")
public class MediaController {

    @Autowired
    private TTerminalInfoService tTerminalInfoService;

    @Autowired
    private TCustomerInfoService tCustomerInfoService;

    @Autowired
    private TOrderService tOrderService;

    @Autowired
    private TTerminalStockService tTerminalStockService;

    @Autowired
    private ToolLocalStorageService toolLocalStorageService;

    @Autowired
    private TServiceInfoService tServiceInfoService;

    @Autowired
    private TMultimediaDao tMultimediaDao;

    /**
     * 根据终端编码集合查询多媒体信息
     *
     * @param
     * @return 所有数据
     */
    @ApiOperation("根据终端编码集合查询多媒体信息")
    @PostMapping("/selectMediaPage")
    public ApiResult<MediaResponseDto> selectMediaPage(@RequestBody MediaQueryRequestDto mediaQueryRequestDto) {
        log.info("---------selectMediaPage begin, mediaQueryRequestDto is {}----------", mediaQueryRequestDto);
        QueryWrapper<TTerminalInfo> queryWrapper = new QueryWrapper<>();
        if (!CollectionUtils.isEmpty(mediaQueryRequestDto.getTerminalCodeList())) {
            queryWrapper.lambda().in(TTerminalInfo::getTerminalCode, mediaQueryRequestDto.getTerminalCodeList());
        } else {
            List<TTerminalStock> tTerminalStockList = tTerminalStockService.list(new QueryWrapper<TTerminalStock>().lambda().ne(TTerminalStock::getOrderCode, ""));
            if (CollectionUtils.isEmpty(tTerminalStockList)) {
                return ApiResult.ok();
            }
            List<String> terminalCodeList = tTerminalStockList.stream().map(TTerminalStock::getTerminalCode).collect(Collectors.toList());
            queryWrapper.lambda().in(TTerminalInfo::getTerminalCode, terminalCodeList);
        }

        List<TTerminalInfo> tTerminalInfoList = tTerminalInfoService.list(queryWrapper);
        if (CollectionUtils.isEmpty(tTerminalInfoList)) {
            return ApiResult.ok();
        }

        List<String> flowCardNumberList = tTerminalInfoList.stream().map(TTerminalInfo::getFlowCardNumber).collect(Collectors.toList());
        QueryWrapper<ToolLocalStorage> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().in(ToolLocalStorage::getFlowCardNumber, flowCardNumberList);
        queryWrapper1.lambda().eq(ToolLocalStorage::getType, mediaQueryRequestDto.getQueryFileType());
        List<ToolLocalStorage> localStorageList = toolLocalStorageService.list(queryWrapper1);
        MediaResponseDto mediaResponseDto = new MediaResponseDto();
        if (MultimediaTypeEnum.SNAP.getValue().equals(mediaQueryRequestDto.getQueryFileType())) {
            //今天时间段
            LocalDateTime lastDayMin1 = DateUtil.getLastDayMin(0);
            LocalDateTime lastDayMax1 = DateUtil.getLastDayMax(0);
            List<ToolLocalStorage> toolLocalStorageList1 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin1) && x.getCreateTime().isBefore(lastDayMax1)).collect(Collectors.toList());
            mediaResponseDto.setOneDayUrlList(toolLocalStorageList1.stream().map(x -> MapServerConstant.URL + x.getPath()).collect(Collectors.toList()));
            //2-7天时间段
            LocalDateTime lastDayMin2 = DateUtil.getLastDayMin(6);
            LocalDateTime lastDayMax2 = DateUtil.getLastDayMax(1);
            List<ToolLocalStorage> toolLocalStorageList2 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin2) && x.getCreateTime().isBefore(lastDayMax2)).collect(Collectors.toList());
            mediaResponseDto.setSevenDayUrlList(toolLocalStorageList2.stream().map(x -> MapServerConstant.URL + x.getPath()).collect(Collectors.toList()));
            //8-30天时间段
            LocalDateTime lastDayMin3 = DateUtil.getLastDayMin(29);
            LocalDateTime lastDayMax3 = DateUtil.getLastDayMax(7);
            List<ToolLocalStorage> toolLocalStorageList3 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin3) && x.getCreateTime().isBefore(lastDayMax3)).collect(Collectors.toList());
            mediaResponseDto.setThirtyDayUrlList(toolLocalStorageList3.stream().map(x -> MapServerConstant.URL + x.getPath()).collect(Collectors.toList()));
            //31天以后
            LocalDateTime lastDayMax4 = DateUtil.getLastDayMax(30);
            List<ToolLocalStorage> toolLocalStorageList4 = localStorageList.stream().filter(x -> x.getCreateTime().isBefore(lastDayMax4)).collect(Collectors.toList());
            mediaResponseDto.setMoreUrlList(toolLocalStorageList4.stream().map(x -> MapServerConstant.URL + x.getPath()).collect(Collectors.toList()));
        } else {
            //今天时间段
            LocalDateTime lastDayMin1 = DateUtil.getLastDayMin(0);
            LocalDateTime lastDayMax1 = DateUtil.getLastDayMax(0);
            List<ToolLocalStorage> toolLocalStorageList1 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin1) && x.getCreateTime().isBefore(lastDayMax1)).collect(Collectors.toList());
            List<MediaSoundResponseDto> oneDayMediaSoundResponseDtoList = toolLocalStorageList1.stream().map(toolLocalStorage -> {
                MediaSoundResponseDto mediaSoundResponseDto = new MediaSoundResponseDto();
                mediaSoundResponseDto.setCreateTime(toolLocalStorage.getCreateTime());
                mediaSoundResponseDto.setSoundFileUrl(MapServerConstant.URL + toolLocalStorage.getPath());
                return mediaSoundResponseDto;
            }).collect(Collectors.toList());
            mediaResponseDto.setOneDaySoundList(oneDayMediaSoundResponseDtoList);
            //2-7天时间段
            LocalDateTime lastDayMin2 = DateUtil.getLastDayMin(6);
            LocalDateTime lastDayMax2 = DateUtil.getLastDayMax(1);
            List<ToolLocalStorage> toolLocalStorageList2 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin2) && x.getCreateTime().isBefore(lastDayMax2)).collect(Collectors.toList());
            List<MediaSoundResponseDto> sevenDayMediaSoundResponseDtoList = toolLocalStorageList2.stream().map(toolLocalStorage -> {
                MediaSoundResponseDto mediaSoundResponseDto = new MediaSoundResponseDto();
                mediaSoundResponseDto.setCreateTime(toolLocalStorage.getCreateTime());
                mediaSoundResponseDto.setSoundFileUrl(MapServerConstant.URL + toolLocalStorage.getPath());
                return mediaSoundResponseDto;
            }).collect(Collectors.toList());
            mediaResponseDto.setSevenDaySoundList(sevenDayMediaSoundResponseDtoList);
            //8-30天时间段
            LocalDateTime lastDayMin3 = DateUtil.getLastDayMin(29);
            LocalDateTime lastDayMax3 = DateUtil.getLastDayMax(7);
            List<ToolLocalStorage> toolLocalStorageList3 = localStorageList.stream().filter(x -> x.getCreateTime().isAfter(lastDayMin3) && x.getCreateTime().isBefore(lastDayMax3)).collect(Collectors.toList());
            List<MediaSoundResponseDto> thirtyDayMediaSoundResponseDtoList = toolLocalStorageList3.stream().map(toolLocalStorage -> {
                MediaSoundResponseDto mediaSoundResponseDto = new MediaSoundResponseDto();
                mediaSoundResponseDto.setCreateTime(toolLocalStorage.getCreateTime());
                mediaSoundResponseDto.setSoundFileUrl(MapServerConstant.URL + toolLocalStorage.getPath());
                return mediaSoundResponseDto;
            }).collect(Collectors.toList());
            mediaResponseDto.setThirtyDaySoundList(thirtyDayMediaSoundResponseDtoList);
            //31天以后
            LocalDateTime lastDayMax4 = DateUtil.getLastDayMax(30);
            List<ToolLocalStorage> toolLocalStorageList4 = localStorageList.stream().filter(x -> x.getCreateTime().isBefore(lastDayMax4)).collect(Collectors.toList());
            List<MediaSoundResponseDto> moreMediaSoundResponseDtoList = toolLocalStorageList4.stream().map(toolLocalStorage -> {
                MediaSoundResponseDto mediaSoundResponseDto = new MediaSoundResponseDto();
                mediaSoundResponseDto.setCreateTime(toolLocalStorage.getCreateTime());
                mediaSoundResponseDto.setSoundFileUrl(MapServerConstant.URL + toolLocalStorage.getPath());
                return mediaSoundResponseDto;
            }).collect(Collectors.toList());
            mediaResponseDto.setMoreSoundList(moreMediaSoundResponseDtoList);
            mediaResponseDto.setThirtyDayUrlList(toolLocalStorageList4.stream().map(x -> MapServerConstant.URL + x.getPath()).collect(Collectors.toList()));
        }
        log.info("---------selectMediaPage end, data is {}----------", mediaResponseDto);
        return ApiResult.ok(mediaResponseDto);
    }

    /**
     * 发送指令
     *
     * @param
     * @return 所有数据
     */
    @ApiOperation("发送指令")
    @PostMapping("/sendCommand")
    @ApiImplicitParams({@ApiImplicitParam(name = "commandType", value = "命令类型 1：图片 2：音频 3：视频"),
            @ApiImplicitParam(name = "terminalCode", value = "设备编码"),
            @ApiImplicitParam(name = "platformMark", value = "标识 1：数据平台需要鉴权，空代表运营平台不需鉴权")})
    @AuthKeyValidated(value = "videoStreaming", validated = true)
    public ApiResult sendCommand(@RequestParam("commandType") String commandType, @RequestParam("terminalCode") String terminalCode, @RequestParam(value = "platformMark", required = false) String platformMark) {
        log.info("---------sendCommand begin, commandType and terminalCode is {},{} and {}----------", commandType, terminalCode, platformMark);
        //如果有值代表是数据平台调用接口  就得校验权限
        TTerminalStock tTerminalStock = tTerminalStockService.getOne(new QueryWrapper<TTerminalStock>().lambda().eq(TTerminalStock::getTerminalCode, terminalCode));
        if (Objects.isNull(tTerminalStock)) {
            throw new MapServerException(ResultErrorEnum.BMKPZ003);
        }
        TOrder tOrder = tOrderService.getOne(new QueryWrapper<TOrder>().lambda().eq(TOrder::getOrderCode, tTerminalStock.getOrderCode()).eq(TOrder::getPaymentStatus, OrderStatusEnum.PAID.getValue()));
        if (Objects.isNull(tOrder)) {
            throw new MapServerException(ResultErrorEnum.BMKPA001);
        }
        if (!StringUtils.isBlank(platformMark)) {
            TServiceInfo tServiceInfo = tServiceInfoService.getOne(new QueryWrapper<TServiceInfo>().lambda().eq(TServiceInfo::getOrderCode, tOrder.getOrderCode()).eq(TServiceInfo::getServiceType, "videoStreaming"));
            if (Objects.isNull(tServiceInfo)) {
                throw new MapServerException(ResultErrorEnum.BMKPF002);
            }
        }
        TTerminalInfo tTerminalInfo = tTerminalInfoService.getOne(new QueryWrapper<TTerminalInfo>().lambda().eq(TTerminalInfo::getTerminalCode, terminalCode));
        //异步执行抓拍指令
        CompletableFuture.runAsync(() -> {
            MediaSendCommandRequestDto mediaSendCommandRequestDto = new MediaSendCommandRequestDto();
            mediaSendCommandRequestDto.setClientId(tTerminalInfo.getFlowCardNumber());
            Map<String, Object> map = BeanUtil.beanToMap(mediaSendCommandRequestDto);
            String result = HttpUtil.post(MapServerConstant.CAMERA_SNAPSHOT, map);
            log.info("调用http://8.141.63.229:97/terminal/camera/snapshot，参数为：{}，返回信息：{}", map, result);
        });
        //添加多媒体记录
        TMultimedia tMultimedia = new TMultimedia();
        tMultimedia.setType(commandType);
        tMultimedia.setTerminalCode(terminalCode);
        tMultimedia.setCustomerCode(tOrder.getCustomerCode());
        tMultimediaDao.insert(tMultimedia);
        return ApiResult.ok();
    }


    /**
     * 发送录音指令
     *
     * @param
     * @return 所有数据
     */
    @ApiOperation("发送录音指令")
    @PostMapping("/sendSoundCommand")
    @ApiImplicitParams({@ApiImplicitParam(name = "terminalCode", value = "设备编码"),
            @ApiImplicitParam(name = "platformMark", value = "标识 1：数据平台需要鉴权，空代表运营平台不需鉴权"),
            @ApiImplicitParam(name = "time", value = "录音时长 单位秒")})
//    @AuthKeyValidated(value = "videoStreaming", validated = true)
    public ApiResult sendCommand(@RequestParam("terminalCode") String terminalCode,
                                 @RequestParam(value = "platformMark", required = false) String platformMark,
                                 @RequestParam(value = "time") int time) {
        log.info("---------sendCommand begin, terminalCode and platformMark is,{} and {}----------", terminalCode, platformMark);
        //如果有值代表是数据平台调用接口  就得校验权限
        TTerminalStock tTerminalStock = tTerminalStockService.getOne(new QueryWrapper<TTerminalStock>().lambda().eq(TTerminalStock::getTerminalCode, terminalCode));
        if (Objects.isNull(tTerminalStock)) {
            throw new MapServerException(ResultErrorEnum.BMKPZ003);
        }
        TOrder tOrder = tOrderService.getOne(new QueryWrapper<TOrder>().lambda().eq(TOrder::getOrderCode, tTerminalStock.getOrderCode()).eq(TOrder::getPaymentStatus, OrderStatusEnum.PAID.getValue()));
        if (Objects.isNull(tOrder)) {
            throw new MapServerException(ResultErrorEnum.BMKPA001);
        }
        if (!StringUtils.isBlank(platformMark)) {
            TServiceInfo tServiceInfo = tServiceInfoService.getOne(new QueryWrapper<TServiceInfo>().lambda().eq(TServiceInfo::getOrderCode, tOrder.getOrderCode()).eq(TServiceInfo::getServiceType, "videoStreaming"));
            if (Objects.isNull(tServiceInfo)) {
                throw new MapServerException(ResultErrorEnum.BMKPF002);
            }
        }
        TTerminalInfo tTerminalInfo = tTerminalInfoService.getOne(new QueryWrapper<TTerminalInfo>().lambda().eq(TTerminalInfo::getTerminalCode, terminalCode));
        //异步执行录音指令
        CompletableFuture.runAsync(() -> {
            //录音开始
            MediaSendSoundCommandRequestDto mediaSendSoundCommandRequestDto = new MediaSendSoundCommandRequestDto();
            mediaSendSoundCommandRequestDto.setClientId(tTerminalInfo.getFlowCardNumber());
            mediaSendSoundCommandRequestDto.setCommand(1);
            mediaSendSoundCommandRequestDto.setSaveSign(0);
            mediaSendSoundCommandRequestDto.setTime(0);
            Map<String, Object> map = BeanUtil.beanToMap(mediaSendSoundCommandRequestDto);
            String result = HttpUtil.post(MapServerConstant.SOUND_RECORD, map);
            log.info("调用http://8.141.63.229:97/terminal/sound_record，参数为：{}，返回信息：{}", map, result);

            try {
                Thread.sleep(time * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //录音结束
            mediaSendSoundCommandRequestDto.setCommand(0);
            Map<String, Object> map1 = BeanUtil.beanToMap(mediaSendSoundCommandRequestDto);
            String result1 = HttpUtil.post(MapServerConstant.SOUND_RECORD, map1);
            log.info("调用http://8.141.63.229:97/terminal/sound_record，参数为：{}，返回信息：{}", map, result1);
            //添加多媒体记录
            TMultimedia tMultimedia = new TMultimedia();
            tMultimedia.setType("2");
            tMultimedia.setTime(time);
            tMultimedia.setTerminalCode(terminalCode);
            tMultimedia.setCustomerCode(tOrder.getCustomerCode());
            tMultimediaDao.insert(tMultimedia);
        });
        return ApiResult.ok();
    }

    /**
     * 根据终端编码集合查询多媒体信息
     *
     * @param
     * @return 所有数据
     */
    @ApiOperation("根据终端编码分页查询图片地址")
    @PostMapping("/selectMediaPageByTerminalCode")
    @AuthKeyValidated(value = "videoStreaming", validated = true)
    public ApiResult<List<String>> selectMediaPageByTerminalCode(@RequestBody MediaQueryRequestPageDto mediaQueryRequestPageDto) {
        log.info("---------selectMediaPageByTerminalCode begin, mediaQueryRequestPageDto is {}----------", mediaQueryRequestPageDto);
        if (StringUtils.isBlank(mediaQueryRequestPageDto.getTerminalCode())) {
            return ApiResult.ok(Collections.emptyList());
        }
        QueryWrapper<ToolLocalStorage> queryWrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(mediaQueryRequestPageDto.getCreateStartTime())) {
            queryWrapper.lambda().ge(ToolLocalStorage::getCreateTime, mediaQueryRequestPageDto.getCreateStartTime());
        }
        if (!ObjectUtils.isEmpty(mediaQueryRequestPageDto.getCreateEndTime())) {
            queryWrapper.lambda().le(ToolLocalStorage::getCreateTime, mediaQueryRequestPageDto.getCreateEndTime());
        }

        TTerminalInfo tTerminalInfo = tTerminalInfoService.getOne(new QueryWrapper<TTerminalInfo>().lambda().eq(TTerminalInfo::getTerminalCode, mediaQueryRequestPageDto.getTerminalCode()));
        if (Objects.isNull(tTerminalInfo)) {
            throw new MapServerException(ResultErrorEnum.BMKPZ003);
        }
        queryWrapper.lambda().eq(ToolLocalStorage::getFlowCardNumber, tTerminalInfo.getFlowCardNumber());

        List<ToolLocalStorage> toolLocalStorageList = toolLocalStorageService.list(queryWrapper);

        List<String> urlList = toolLocalStorageList.stream().map(toolLocalStorage -> MapServerConstant.URL + toolLocalStorage.getPath()).collect(Collectors.toList());
        log.info("---------selectMediaPageByTerminalCode end, data is {}----------", mediaQueryRequestPageDto);
        return ApiResult.ok(urlList);
    }

//    public static void main(String[] args) {
//        MediaSendSoundCommandRequestDto mediaSendSoundCommandRequestDto = new MediaSendSoundCommandRequestDto();
//        mediaSendSoundCommandRequestDto.setClientId("111");
//        mediaSendSoundCommandRequestDto.setCommand(1);
//        mediaSendSoundCommandRequestDto.setSaveSign(0);
//        mediaSendSoundCommandRequestDto.setTime(0);
//        Map<String, Object> map = BeanUtil.beanToMap(mediaSendSoundCommandRequestDto);
//        String result = HttpUtil.post(MapServerConstant.SOUND_RECORD, map);
//        log.info("调用http://8.141.63.229:97/terminal/sound_record，参数为：{}，返回信息：{}", map, result);
//    }
}
